import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class Test {
    static class MytestClass{

    }
        public static void main(String args[]) throws NoSuchFieldException, IllegalAccessException {
            // 当容量为1时,超出只扩容1
//		parameterBuilderTest(1,2);
            // 当容量不为1时,超出只扩容1.5倍
//		parameterBuilderTest(8,9);
            int MAX_ARRAY_SIZE = Integer.MAX_VALUE-8;
            parameterBuilderTest2(1431655757,1431655758);
            Scanner sc = new Scanner(System.in);
            sc.next();
//		System.out.println(MAX_ARRAY_SIZE/3*2);
//		parameterBuilderTestSizeTest(1,2);
//		expansionSize(1);
        }
    //无参构造测试
    public void noParameterBuilderTest() throws NoSuchFieldException, IllegalAccessException {
        // initialCapacity = DEFAULT_CAPACITY = 10 无参默认容量为10
        ArrayList arrayList = new ArrayList();
        System.out.println(getElementDataLength(arrayList));
    }

    //无参构造测试,再调用add()测试
    public void noParameterBuilderTest(int addObjectLength) throws NoSuchFieldException, IllegalAccessException {
        // initialCapacity = DEFAULT_CAPACITY = 10 无参默认容量为10
        ArrayList arrayList = new ArrayList();
        addObject(arrayList,addObjectLength);
        System.out.println(getElementDataLength(arrayList));
    }

    //有参构造测试
    public void parameterBuilderTest(int initialCapacity) throws NoSuchFieldException, IllegalAccessException {
        ArrayList arrayList = new ArrayList(initialCapacity);
        System.out.println(getElementDataLength(arrayList));
    }

    //有参构造,再调用add()测试
    public void parameterBuilderTest(int initialCapacity,int addObjectLength) throws NoSuchFieldException, IllegalAccessException {
        ArrayList arrayList = new ArrayList(initialCapacity);
        addObject(arrayList,addObjectLength);
        System.out.println(getElementDataLength(arrayList));
    }

    //有参构造,再调用add()添加mytestClass测试
    public static void parameterBuilderTest2(int initialCapacity, int addObjectLength) throws NoSuchFieldException, IllegalAccessException {
        ArrayList<MytestClass> arrayList = new ArrayList<>(initialCapacity);
        addMytestClass(arrayList,addObjectLength);
        System.out.println(getElementDataLength(arrayList));
    }

    //size测试
    public void parameterBuilderTestSizeTest(int initialCapacity,int addObjectLength) throws NoSuchFieldException, IllegalAccessException {
        ArrayList arrayList = new ArrayList(initialCapacity);
        System.out.println("构造后:"+getSize(arrayList));
        addObject(arrayList,addObjectLength);
        System.out.println("调用add后:"+getSize(arrayList));
    }



    public void addObject(List list, int len) throws NoSuchFieldException, IllegalAccessException {
        for(int i = 0;i<len;i++) {
            list.add("Object "+i);
        }
    }
    public static void addMytestClass(List list, int len) throws NoSuchFieldException, IllegalAccessException {
        for(int i = 0;i<len;i++) {
            MytestClass mytestClass = new MytestClass();
            list.add(mytestClass);
        }
    }

    public static String getElementDataLength(List list) throws NoSuchFieldException, IllegalAccessException {
        Class<? extends List> strClass = list.getClass();
        Field field = strClass.getDeclaredField("elementData");
        field.setAccessible(true);
        Object[] elementData = (Object[]) field.get(list);
        return "这个ArrayList的容量为："+elementData.length+
                ",这个ArrayList中元素的个数为"+list.size();
    }

    public String getSize(List list) throws NoSuchFieldException, IllegalAccessException {
        Class<? extends List> strClass = list.getClass();
        Field field = strClass.getDeclaredField("size");
        field.setAccessible(true);
        int size = (Integer) field.get(list);
        return "这个ArrayList的size为："+size;
    }

    public void expansionSize(int oldCapacity){
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        System.out.println("(oldCapacity >> 1):"+(oldCapacity >> 1));
        System.out.println("newCapacity:"+newCapacity);
        int minCapacity = 2;
    }

    // Arraylist 扩容核心代码,每次扩容增加
    private void grow(Object[] elementData,int minCapacity) {
        // 常量
        int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);

    }

    private static int hugeCapacity(int minCapacity) {
        int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
                Integer.MAX_VALUE :
                MAX_ARRAY_SIZE;
    }


}
